#! /usr/bin/env python
import roslib;roslib.load_manifest('robina_reporter')

import datetime
from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib
import rospy
from std_msgs.msg import String,Bool
from robina_reporter.srv import Report 
import socket
import json
import time
import thread
pub=None
pub_guide=None
serv =None

is_report_available=False
report_text=None
mode='normal'


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#s.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE,1)
#s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 1)
#s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 1)
#s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 5)
s.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,True)
s.bind(("0.0.0.0", 44000))
s.listen(1)

#s.settimeout(2000)
conn=None




d="""
import actionlib
from robina_dashBoard.srv import *
from robina_dashBoard.msg import *
from move_base_msgs.msg import *
from std_srvs.srv import *
from geometry_msgs.msg import *
from std_msgs.msg import *
from std_srvs.srv import *
#from rerun_move_base.srv import *
 
from actionlib.simple_action_client import SimpleGoalState

class Navigation:
    def __init__(self):
        #marker handler server initialize
        rospy.wait_for_service('get_marker')
        self.getMarker = rospy.ServiceProxy('/get_marker',get_marker)
         
        rospy.wait_for_service('get_markers')
        self.getMarkers = rospy.ServiceProxy('/get_markers',get_markers)        
        rospy.wait_for_service('set_marker')
        self.setMarker = rospy.ServiceProxy('/set_marker',set_marker)
    def goto(self,position,wait=True):
        t=type(position)
        marker_pose = PoseStamped()
         
        if t==str: # position is the name of the position so we need to get exact position from the getMarker
            marker_pose.pose = self.getMarkerPose(position).pose.pose
            self.move_base_action_client(marker_pose,wait)
            return self.move_base_action_client(marker_pose,wait)
        #need to goto position action
        elif t==PoseStamped: #position is a Pose it needs to make a poseStamp from it
            marker_pose.pose = position.pose
            return self.move_base_action_client(marker_pose,wait)
        else: 
            rospy.logerr("Type %s is invalid",[t.__name__])
            return False     
    def move_base_action_client(self,marker_pose,wait):
        #initialize move base action        
        moveBaseClient = actionlib.SimpleActionClient('move_base',MoveBaseAction)
        moveBaseClient.wait_for_server()
        goal_move_base = MoveBaseGoal()
        goal_move_base.target_pose.pose = marker_pose.pose
        goal_move_base.target_pose.header.frame_id = '/map'
        goal_move_base.target_pose.header.stamp = rospy.Time.now()
        #print goal_move_base
        moveBaseClient.send_goal(goal_move_base)
        if wait:
            moveBaseClient.wait_for_result()
        return True
        if moveBaseClient.get_state() == SimpleGoalState.DONE:
            return True
        else:
            return False
    def getMarkerPose(self,position_name):
        return self.getMarker(position_name).get_marker_res
        #return positions of marker
    def getMarkersPoses(self):
        return self.getMarkers().get_markers_res
        #return all of positions and names
    def setMarkersPoses(self,marker_name,use_custom_pose,marker_pose):
        self.setMarker(marker_name,use_custom_pose,marker_pose)
        #not debugged
    def approchToGraspingPoint(self,dist):
        pass #service
    def goToPostion(self,position_name):
        #navigation initialize        
        moveBaseClient = actionlib.SimpleActionClient('move_base',MoveBaseAction)
        moveBaseClient.wait_for_server()
        marker_pose = PoseStamped()
        marker_pose.pose = self.getMarkerPose(position_name).pose.pose
	    #print marker_pose.pose
        goal_move_base = MoveBaseGoal()
        goal_move_base.target_pose.pose = marker_pose.pose
        goal_move_base.target_pose.header.frame_id = '/map'
        goal_move_base.target_pose.header.stamp = rospy.Time.now()
	    #print goal_move_base
        moveBaseClient.send_goal(goal_move_base)
        moveBaseClient.wait_for_result()
        return True
"""
def tcp_keep_connect():
    while True:
        try:
	    print "Hell"
            print conn.send('hello')
	    time.sleep(1)
        except socket.error as e:
	    print e
	    break
	except:
	    print 'fuck'

def tcp_thread():
    global conn,s
    while 1:
        print 'waiting'
        conn, addr = s.accept()
	conn.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,True)
	conn.settimeout(1000)
	#thread.start_new_thread(tcp_keep_connect,())
        print 'Connection address:', addr
        while 1:
            try:
            	data = conn.recv(1024)
            except socket.error: break
	    except: break
            if not data: 
                print '**', data
                break
            print "received data:", data,"-"
    
            conn.send(data)  # echo
        print 'closed'
        conn.close()


def handleReportService(req):
    global is_report_available,report_text

    name=str(req.name.data)
    #generate(report_text)
    is_report_available=True
    if conn!=None:
	print 
        conn.send(gen_json(name))
    
    msg=Bool()
    msg.data=True
    print 'ddddd'
    return msg

def setreportstate(x):
    print x    
    pub.publish(x)
    mode=x
    return True

def getMode():
	return mode

def gen_json(name):
    a={"topic":"Guest","data":{"Name":name,"Image":"http://192.168.20.210:7878/pics/{0}.jpg".format(name)}}
    return json.dumps(a)

def generate(name):
    import time
    a="""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Report</title>
    <meta name="author" content="Navid" >
    <meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8">
    <meta http-equiv="content-style-type" content="text/css">
    <meta http-equiv="expires" content="0">
    </head>
    <body>
        <div style="text-align: center"><b>Name:  </b> <h1>{0}</h1></div><br />
        <div style="text-align: center">
   	<img src="/pics/{0}.jpg" alt="" />
    </div><br />
    <div style="text-align: center"><h1>Time: {1}</h1></div><br />
    </body>
    </html>"""
    f=open("/home/athome/android_server/report.html",'w')
    f.write(a.format(name,time.asctime()))

def report(x):
    global is_report_available,mode
    print x
    pub.publish(x)
    return is_report_available

def recieveReport():
    global is_report_available,report_text
    generate(report_text)
    if is_report_available:
        is_report_available=False
        return  "http://192.168.0.241:7878/report.html"
    return "NO REPORT"

def getLocations():
    import sqlite3
    locations=[]
    conn = sqlite3.connect('/home/athome/dataBase')
    c = conn.cursor()
    for row in c.execute('SELECT * FROM locationMarker ORDER BY name'):
        a="X={0}\tY={1}\tTheta={2}".format(round(row[1],2),round(row[2],2),round(row[6]*180/3.14))
        locations.append((row[0],a))
    return locations

def goto(location):
   	#nav=Navigation()
	pub_guide.publish(location)
   	#nav.goto(location)
    	print location
	#pub_guide.publish(location)
   	return True

  
def main():
    global pub,pub_guide,serv
    rospy.init_node('robina_reporter')
    pub=rospy.Publisher('/report_state',String )
    pub_guide=rospy.Publisher('/guide',String )
    serv=rospy.Service("/Report", Report, handleReportService)
    server = SimpleXMLRPCServer(("0.0.0.0", 9090))
    print "Listening on port 9090..."
    server.register_function(setreportstate, "setMode")
    server.register_function(getMode, "getMode")
    server.register_function(report, "report")
    server.register_function(getLocations, "getLocations")
    server.register_function(recieveReport, "recievereport")
    server.register_function(goto)
    thread.start_new_thread(tcp_thread,())
    #thread.start_new_thread(tcp_thread,())
    server.serve_forever()
    s.close()
main()
